package com.struts;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.listener.ActionMapping;

public class MainServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2212853105561369694L;

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		//super.doPost(req, resp);//
		Map<String,ActionMapping> map=(Map<String,ActionMapping>)req.getSession().getServletContext().getAttribute("struts");
		
		String path=req.getServletPath();
		execute(map.get(path.substring(1, path.lastIndexOf("."))), req, resp);
		
		
	}

	
	
	

	public  String execute(ActionMapping action ,HttpServletRequest req,HttpServletResponse resp){
		String returl="";
		try {
			
			Class c=Class.forName(action.getType());
			Object o=c.newInstance();
			
			injectObject(c, req, o);
			Method me=c.getMethod(action.getMethod(),null);
			String ret=me.invoke(o,new Object[]{}).toString();
		
			returl=action.getForward().get(ret);
			req.getRequestDispatcher(returl).forward(req, resp);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		return returl;

	}
		
	public  void injectObject(Class c,HttpServletRequest req,Object o){ 
		try{
		Field[] f=c.getDeclaredFields();
		
		for(Field ff:f){
			String ffname=ff.getName();
			Method md=c.getMethod("set"+ffname.replace(ffname.substring(0,1), ffname.substring(0,1).toUpperCase()),ff.getType());
			String simplename=ff.getType().getSimpleName();
			System.out.println(simplename);
			Object obj=null;
			String val=req.getParameter(ffname);
			if("String".equals(simplename)){
				md.invoke(o, new Object[]{val});
			}
			
			else if("int".equals(simplename)){
				
				md.invoke(o, new Object[]{Integer.parseInt(val)});
				
			}else if("float".equals(simplename)){
				
				md.invoke(o, new Object[]{Float.parseFloat(val)});

			}else if("long".equals(simplename)){
				md.invoke(o, new Object[]{Long.parseLong(val)});

				
			}else if("double".equals(simplename)){
				md.invoke(o, new Object[]{Double.parseDouble(val)});

				
			}else if("boolean".equals(simplename)){
				boolean b=true;
				if(val==null || "".equals(val)){
					
					b=false;
				}
				md.invoke(o, new Object[]{b});

			}else{
				String fname=ff.getName();
				Class clazz=Class.forName(ff.getType().getName());
				 obj=clazz.newInstance();
				Field[] fd=clazz.getDeclaredFields();
				for(Field fs:fd){
					String fname1=fs.getName();
					
			Method me=clazz.getMethod("set"+fname1.replace(fname1.substring(0,1), fname1.substring(0,1).toUpperCase()),fs.getType());
					
					me.invoke(obj, new Object[]{req.getParameter(fname+"."+fname1)});
				}
				
				md.invoke(o, obj);
		}	
			
		
	}}catch (Exception e) {
		// TODO: handle exception
		e.getStackTrace();
	}
		
		}
		
			
			
	
	
}
